﻿using ProjScan.Config;
using ProjScan.Tools;
using System;
using System.Collections.Generic;
using System.Text.RegularExpressions;
using UnityEditor;
using UnityEditor.IMGUI.Controls;
using UnityEngine;

namespace ProjScan.ScanGUI.Tools
{
    internal class ScanAssetsConfigTreeView : TreeView
    {
        private class DescendingComparer : IComparer<ScanAssetsConfig>
        {
            public int Compare(ScanAssetsConfig config1, ScanAssetsConfig config2)
            {
                try
                {
                    if (float.Parse(config1.thresholds[0]) < float.Parse(config2.thresholds[0]))
                    {
                        return 1;
                    }

                    return -1;
                }
                catch (Exception ex)
                {
                    Debug.LogError("ThresholdRowsCompare Exception " + ex.Message);
                    return 0;
                }
            }
        }

        private class AscendingComparer : IComparer<ScanAssetsConfig>
        {
            public int Compare(ScanAssetsConfig config1, ScanAssetsConfig config2)
            {
                try
                {
                    if (float.Parse(config1.thresholds[0]) < float.Parse(config2.thresholds[0]))
                    {
                        return -1;
                    }

                    return 1;
                }
                catch (Exception ex)
                {
                    Debug.LogError("ThresholdRowsCompare Exception " + ex.Message);
                    return 0;
                }
            }
        }

        private List<ScanAssetsConfig> _scanAssetsConfigs;

        private readonly List<TreeViewItem> _treeViewItems;

        private TreeViewItem _rootTreeViewItem;

        private string _id;

        private bool _hasDefaultValue;

        public bool isLimitEnabled;

        public int maxConfigCount;

        public bool minConfigCountToggle;

        private int _thresholdCompare;

        private float[] _defaultThresholds;

        private string[] _thresholdDescriptions;

        private string _defaultAssetPath;

        //
        // 摘要:
        //     title
        public string title;

        private Rect _allTreeRect;

        private Rect _treeRect;

        private Rect _addRemoveBtnRect;

        private IComparer<ScanAssetsConfig> _thresholdAscendingComparer;

        private IComparer<ScanAssetsConfig> _thresholdDescendingComparer;

        private string DefaultPath;

        private string DefaultRegex;

        public ScanAssetsConfigTreeView(string id, string title, TreeViewState treeViewState, MultiColumnHeader multiColumnHeader, bool hasDefaultValue, float[] thresholdDefault, string[] thresholdDescription, int thresholdCpmpare, List<ScanAssetsConfig> datas, string defaultAssetsPath)
            : base(treeViewState, multiColumnHeader)
        {
            _treeViewItems = new List<TreeViewItem>();
            _rootTreeViewItem = new TreeViewItem(-1, -1, "root");
            _hasDefaultValue = false;
            isLimitEnabled = true;
            maxConfigCount = 5;
            minConfigCountToggle = true;
            _thresholdCompare = 0;
            this.title = "";
            _allTreeRect = new Rect(0f, 0f, 200f, 0f);
            _treeRect = default(Rect);
            _addRemoveBtnRect = default(Rect);
            _thresholdAscendingComparer = new AscendingComparer();
            _thresholdDescendingComparer = new DescendingComparer();
            DefaultPath = "Assets";
            DefaultRegex = "Assets[/].*";
            _id = id;
            _hasDefaultValue = hasDefaultValue;
            _defaultThresholds = thresholdDefault;
            _thresholdDescriptions = thresholdDescription;
            _thresholdCompare = thresholdCpmpare;
            _scanAssetsConfigs = datas;
            base.rowHeight = 22f;
            base.showAlternatingRowBackgrounds = true;
            _defaultAssetPath = defaultAssetsPath;
            Reload();
        }

        protected override TreeViewItem BuildRoot()
        {
            return _rootTreeViewItem;
        }

        protected override IList<TreeViewItem> BuildRows(TreeViewItem treeViewItem_1)
        {
            IComparer<ScanAssetsConfig> comparer = null;
            if (_hasDefaultValue)
            {
                comparer = ((_thresholdCompare != 0) ? _thresholdDescendingComparer : _thresholdAscendingComparer);
                _scanAssetsConfigs.Sort(comparer);
            }

            _treeViewItems.Clear();
            if (_scanAssetsConfigs != null)
            {
                for (int i = 0; i < _scanAssetsConfigs.Count; i++)
                {
                    TableCellItem item = new TableCellItem(_scanAssetsConfigs[i], i);
                    _treeViewItems.Add(item);
                }
            }

            TreeView.SetupParentsAndChildrenFromDepths(treeViewItem_1, _treeViewItems);
            return _treeViewItems;
        }

        protected override bool CanMultiSelect(TreeViewItem treeViewItem_1)
        {
            return false;
        }

        protected override void DoubleClickedItem(int int_2)
        {
        }

        protected override void RowGUI(RowGUIArgs args)
        {
            TableCellItem tableCellItem = (TableCellItem)args.item;
            for (int i = 0; i < args.GetNumVisibleColumns(); i++)
            {
                Rect cellRect = args.GetCellRect(i);
                RenderTableCell(cellRect, tableCellItem, args.GetColumn(i));
            }
        }

        private void RenderTableCell(Rect tableCellRect, TableCellItem tableCellItem, int columnId)
        {
            CenterRectUsingSingleLineHeight(ref tableCellRect);
            string text = _id + "-MatchStr-" + tableCellItem.id;
            string text2 = _id + "-Threshold-" + tableCellItem.id;
            switch (columnId)
            {
                case 0:
                    {
                        GUIStyle gUIStyle2 = new GUIStyle("MiniPopup");
                        gUIStyle2.alignment = TextAnchor.MiddleCenter;
                        gUIStyle2.fontSize = 14;
                        int matchingType = (int)tableCellItem.assetsConfig.matchingType;
                        string[] displayedOptions2 = new string[2]
                        {
                    "路径",
                    "正则"
                        };
                        tableCellItem.assetsConfig.matchingType = (MatchingType)EditorGUI.Popup(tableCellRect, (int)tableCellItem.assetsConfig.matchingType, displayedOptions2, gUIStyle2);
                        if (tableCellItem.assetsConfig.matchingType != (MatchingType)matchingType)
                        {
                            GUI.FocusControl(text);
                        }

                        break;
                    }
                case 1:
                    {
                        tableCellRect.x += 2f;
                        tableCellRect.width -= 4f;
                        GUI.SetNextControlName(text);
                        string text3 = EditorGUI.TextField(tableCellRect, tableCellItem.assetsConfig.assetPath).Trim();
                        if (GUI.GetNameOfFocusedControl() == text)
                        {
                            tableCellItem.isAssetPathFocused = true;
                        }

                        if (tableCellItem.isAssetPathFocused && GUI.GetNameOfFocusedControl() != text)
                        {
                            tableCellItem.isAssetPathFocused = false;
                            if (tableCellItem.assetsConfig.matchingType != 0)
                            {
                                if (tableCellItem.assetsConfig.matchingType == MatchingType.regex && !IsStringValidRegex(text3))
                                {
                                    Debug.LogWarning("提示：正则表达式不合法，已回退。");
                                    text3 = tableCellItem.assetsConfig.assetPath;
                                    if (!IsStringValidRegex(text3))
                                    {
                                        Debug.LogWarning("提示：正则表达式不合法，已替换为默认表达式。");
                                        text3 = DefaultRegex;
                                        GUI.changed = true;
                                    }
                                    else
                                    {
                                        GUI.changed = true;
                                    }
                                }
                            }
                            else
                            {
                                if (text3.Contains("\\"))
                                {
                                    Debug.Log("提示：路径分隔符请使用正斜杠\"/\"");
                                    text3 = ToolsHelper.DirConvert(text3);
                                }

                                if (text3.EndsWith("/"))
                                {
                                    text3 = text3.Substring(0, text3.Length - 1);
                                }

                                if (IsAssetPathValid(text3))
                                {
                                    text3 = ToolsHelper.ConvertAbsolutePathToRelative(text3);
                                    GUI.changed = true;
                                }
                                else
                                {
                                    Debug.LogWarning("提示：路径填写不合法，已回退。");
                                    text3 = tableCellItem.assetsConfig.assetPath;
                                    if (!IsAssetPathValid(text3))
                                    {
                                        Debug.LogWarning("提示：路径填写不合法，已替换为默认路径。");
                                        text3 = DefaultPath;
                                    }

                                    GUI.changed = true;
                                }
                            }
                        }

                        tableCellItem.assetsConfig.assetPath = text3;
                        break;
                    }
                case 2:
                    {
                        Rect position = tableCellRect;
                        position.width = 65f;
                        Rect position2 = tableCellRect;
                        position2.width = tableCellRect.width / (float)tableCellItem.assetsConfig.thresholds.Length - position.width;
                        if (_thresholdDescriptions == null)
                        {
                            throw new Exception("阈值描述信息丢失");
                        }

                        if (_thresholdDescriptions.Length == _defaultThresholds.Length)
                        {
                            GUIStyle tStyle = Singleton<GUIStyleManager>.Instance.GetTStyle(TStyle.LargeLabel);
                            for (int i = 0; i < tableCellItem.assetsConfig.thresholds.Length; i++)
                            {
                                string text4 = _thresholdDescriptions[i];
                                if (_thresholdCompare == 0)
                                {
                                    text4 += "<";
                                }
                                else if (_thresholdCompare == 1)
                                {
                                    text4 += ">";
                                }

                                position.width = ToolsHelper.CalcSize(tStyle, text4).x + 3f;
                                position2.width = tableCellRect.width / (float)tableCellItem.assetsConfig.thresholds.Length - position.width;
                                position2.x = tableCellRect.x + (float)i * tableCellRect.width / (float)tableCellItem.assetsConfig.thresholds.Length + position.width;
                                GUI.SetNextControlName(text2);
                                string text5 = EditorGUI.TextField(position2, tableCellItem.assetsConfig.thresholds[i]);
                                if (GUI.GetNameOfFocusedControl() == text2)
                                {
                                    tableCellItem.isThresholdFocused = true;
                                }

                                if (tableCellItem.isThresholdFocused && GUI.GetNameOfFocusedControl() != text2)
                                {
                                    tableCellItem.isThresholdFocused = false;
                                    if (string.IsNullOrEmpty(text5))
                                    {
                                        text5 = _defaultThresholds[i].ToString();
                                    }

                                    if (!IsStringNonNegativeFloatNumber(text5))
                                    {
                                        EditorUtility.DisplayDialog("提示", "请输入合法的非负浮点数。", "确认");
                                        text5 = tableCellItem.assetsConfig.thresholds[i];
                                        if (!IsStringNonNegativeFloatNumber(text5))
                                        {
                                            text5 = _defaultThresholds[i].ToString();
                                        }

                                        GUI.changed = true;
                                    }

                                    ReBuildRows();
                                }

                                tableCellItem.assetsConfig.thresholds[i] = text5;
                                position.x = tableCellRect.x + (float)i * tableCellRect.width / (float)tableCellItem.assetsConfig.thresholds.Length + 3f;
                                EditorGUI.LabelField(position, text4, tStyle);
                            }
                        }
                        else
                        {
                            for (int j = 0; j < tableCellItem.assetsConfig.thresholds.Length; j++)
                            {
                                position2.x += (float)j * tableCellRect.width / (float)tableCellItem.assetsConfig.thresholds.Length;
                                tableCellItem.assetsConfig.thresholds[j] = EditorGUI.LongField(position2, long.Parse(tableCellItem.assetsConfig.thresholds[j])).ToString();
                            }
                        }

                        break;
                    }
                case 3:
                    if (_hasDefaultValue)
                    {
                        GUIStyle gUIStyle = new GUIStyle("MiniPopup");
                        gUIStyle.alignment = TextAnchor.MiddleCenter;
                        gUIStyle.fontSize = 14;
                        string[] displayedOptions = new string[3]
                        {
                        "默认",
                        "中",
                        "高"
                        };
                        tableCellItem.assetsConfig.priority = (ThresholdPriority)EditorGUI.Popup(tableCellRect, (int)tableCellItem.assetsConfig.priority, displayedOptions, gUIStyle);
                    }

                    break;
            }
        }

        private static bool IsStringValidRegex(string string_6)
        {
            try
            {
                if (string.IsNullOrEmpty(string_6))
                {
                    return false;
                }

                new Regex(string_6);
            }
            catch (ArgumentException)
            {
                return false;
            }

            return true;
        }

        private static bool IsAssetPathValid(string assetPath)
        {
            if (string.IsNullOrEmpty(assetPath))
            {
                return false;
            }

            if (assetPath.StartsWith("Assets", StringComparison.OrdinalIgnoreCase))
            {
                return true;
            }

            if (assetPath.StartsWith(Application.dataPath, StringComparison.OrdinalIgnoreCase))
            {
                return true;
            }

            try
            {
                Uri uri = new Uri(assetPath);
                Uri uri2 = new Uri(Application.dataPath + "/");
                if (string.IsNullOrEmpty(uri2.MakeRelativeUri(uri).ToString()))
                {
                    throw new Exception("Failed to get relative path");
                }

                return true;
            }
            catch (Exception)
            {
                return false;
            }
        }

        public static bool IsStringNonNegativeFloatNumber(string string_6)
        {
            try
            {
                if (float.Parse(string_6) < 0f)
                {
                    return false;
                }

                return true;
            }
            catch (Exception)
            {
                return false;
            }
        }

        public override void OnGUI(Rect rect)
        {
            base.OnGUI(rect);
            if (GUI.changed)
            {
                UpdateScanAssetConfigs();
            }
        }

        public void UpdateScanAssetConfigs()
        {
            for (int i = 0; i < _treeViewItems.Count; i++)
            {
                TableCellItem tableCellItem = (TableCellItem)_treeViewItems[i];
                if (tableCellItem != null)
                {
                    _scanAssetsConfigs[i] = tableCellItem.assetsConfig;
                }
            }
        }

        //
        // 摘要:
        //     Draw
        public void Draw()
        {
            DrawTitle();
            Rect rectForTreeView = GetRectForTreeView();
            DrawABoxShadow(rectForTreeView);
            RenderTreeView();
            RenderAddRemoveButton();
        }

        private void DrawTitle()
        {
            if (!string.IsNullOrEmpty(title))
            {
                GUILayout.Label(title + $"(已添加 {_scanAssetsConfigs.Count} 个): ");
            }
        }

        public Rect GetRectForTreeView()
        {
            float height = base.multiColumnHeader.height + (float)(_treeViewItems.Count + 2) * base.rowHeight + 5f;
            return GUILayoutUtility.GetRect(0f, height);
        }

        private void DrawABoxShadow(Rect rect_3)
        {
            _treeRect.x = rect_3.x + 4f;
            _treeRect.y = rect_3.y;
            _treeRect.width = rect_3.width - 8f;
            _treeRect.height = base.multiColumnHeader.height + (float)(_treeViewItems.Count + 2) * base.rowHeight + 5f;
            GUITools.DrawBoxShadow(_treeRect, 1f);
        }

        private void RenderTreeView()
        {
            _addRemoveBtnRect.x = _treeRect.x;
            _addRemoveBtnRect.y = _treeRect.y;
            _addRemoveBtnRect.width = _treeRect.width - 100f;
            _addRemoveBtnRect.height = _treeRect.height;
            OnGUI(_addRemoveBtnRect);
        }

        private void RenderAddRemoveButton()
        {
            _allTreeRect.x = _addRemoveBtnRect.xMax;
            _allTreeRect.y = _addRemoveBtnRect.y;
            _allTreeRect.height = _addRemoveBtnRect.height;
            _allTreeRect.width = 100f;
            GUITools.DrawBox(_allTreeRect, new Color(0.2196f, 0.2196f, 0.2196f));
            GUIStyle gUIStyle = new GUIStyle(GUI.skin.button);
            gUIStyle.fontSize = 13;
            gUIStyle.alignment = TextAnchor.MiddleLeft;
            float num = _allTreeRect.width / 1.3f;
            float height = base.rowHeight - 1f;
            float x = _allTreeRect.x + _allTreeRect.width / 2f - num / 2f;
            float num2 = 0f;
            if (!IsTreeViewItemAtLeastOne())
            {
                for (int i = 0; i < _treeViewItems.Count; i++)
                {
                    num2 = (float)i * base.rowHeight + _allTreeRect.y + base.multiColumnHeader.height;
                    Rect position = new Rect(x, num2, num, height);
                    GUI.SetNextControlName("BtnRemove");
                    if (GUI.Button(position, "删除[ - ]", gUIStyle))
                    {
                        RemoveAt(i);
                        GUI.FocusControl("BtnRemove");
                    }
                }
            }

            num2 = (float)(_treeViewItems.Count + 1) * base.rowHeight + _allTreeRect.y + base.multiColumnHeader.height;
            Rect position2 = new Rect(x, num2, num, height);
            if (GUI.Button(position2, "添加[ + ]", gUIStyle))
            {
                if (!IsTreeViewItemOverLimit())
                {
                    AddScanAssetsCongfig();
                }
                else
                {
                    EditorUtility.DisplayDialog("提示", "最多支持5个自定义阈值配置！", "确认");
                }
            }
        }

        public void ReBuildRows()
        {
            BuildRows(_rootTreeViewItem);
        }

        public void AddScanAssetsCongfig()
        {
            ScanAssetsConfig item = default(ScanAssetsConfig);
            item.assetPath = _defaultAssetPath;
            item.thresholds = ToolsHelper.ConvertToStringArray(_defaultThresholds);
            _scanAssetsConfigs.Add(item);
            ReBuildRows();
        }

        public void RemoveAt(int int_2)
        {
            _scanAssetsConfigs.RemoveAt(int_2);
            ReBuildRows();
        }

        private bool IsTreeViewItemOverLimit()
        {
            if (!isLimitEnabled)
            {
                return false;
            }

            return _treeViewItems.Count >= maxConfigCount;
        }

        private bool IsTreeViewItemAtLeastOne()
        {
            if (!minConfigCountToggle)
            {
                return false;
            }

            return _treeViewItems.Count <= 1;
        }

        public static ScanAssetsConfigTreeView Create(string id, string title, bool hasDefaultValue, float[] thresholdDefault, string[] thresholdDescription, int thresholdCpmpare, ref List<ScanAssetsConfig> datas, GUIContent pathTitle, string defaultAssetsPath)
        {
            TreeViewState treeViewState = new TreeViewState();
            ThresholdDataColumnHeader thresholdDataColumnHeader = new ThresholdDataColumnHeader(CreateColumnHeader(hasDefaultValue, pathTitle));
            thresholdDataColumnHeader.ResizeToFit();
            ScanAssetsConfigTreeView scanAssetsConfigTreeView = new ScanAssetsConfigTreeView(id, title, treeViewState, thresholdDataColumnHeader, hasDefaultValue, thresholdDefault, thresholdDescription, thresholdCpmpare, datas, defaultAssetsPath);
            scanAssetsConfigTreeView.title = title;
            return scanAssetsConfigTreeView;
        }

        public static MultiColumnHeaderState CreateColumnHeader(bool hasDefaultValue, GUIContent HeadTitle)
        {
            GUIContent gUIContent = null;
            if (HeadTitle == null || string.IsNullOrEmpty(HeadTitle.text))
            {
                throw new Exception("没有设置关键列的表头");
            }

            gUIContent = HeadTitle;
            Column[] array = new Column[2];
            Column column = new Column();
            column.headerContent = new GUIContent("匹配方式", "路径 / 正则");
            column.headerTextAlignment = TextAlignment.Center;
            column.sortedAscending = false;
            column.sortingArrowAlignment = TextAlignment.Left;
            column.width = 100f;
            column.minWidth = 100f;
            column.maxWidth = 100f;
            column.autoResize = true;
            column.canSort = false;
            column.allowToggleVisibility = false;
            array[0] = column;
            Column column2 = new Column();
            column2.headerContent = gUIContent;
            column2.headerTextAlignment = TextAlignment.Left;
            column2.sortedAscending = false;
            column2.sortingArrowAlignment = TextAlignment.Center;
            column2.width = 225f;
            column2.minWidth = 100f;
            column2.maxWidth = 900f;
            column2.autoResize = true;
            column2.allowToggleVisibility = false;
            column2.canSort = false;
            array[1] = column2;
            Column[] array2 = array;
            if (hasDefaultValue)
            {
                Array.Resize(ref array2, array2.Length + 1);
                Column column3 = new Column();
                column3.headerContent = new GUIContent("阈值", "规则阈值");
                column3.headerTextAlignment = TextAlignment.Center;
                column3.sortedAscending = false;
                column3.sortingArrowAlignment = TextAlignment.Left;
                column3.width = 150f;
                column3.minWidth = 100f;
                column3.maxWidth = 450f;
                column3.autoResize = true;
                column3.canSort = false;
                column3.allowToggleVisibility = false;
                array2[^1] = column3;
                Array.Resize(ref array2, array2.Length + 1);
                Column column4 = new Column();
                column4.headerContent = new GUIContent("优先级", "优先级越高，越优先将资源归入");
                column4.headerTextAlignment = TextAlignment.Center;
                column4.sortedAscending = false;
                column4.sortingArrowAlignment = TextAlignment.Left;
                column4.width = 100f;
                column4.minWidth = 100f;
                column4.maxWidth = 100f;
                column4.autoResize = false;
                column4.allowToggleVisibility = false;
                column4.canSort = false;
                array2[^1] = column4;
            }

            MultiColumnHeaderState.Column[] columns = array2;
            return new MultiColumnHeaderState(columns);
        }
    }
}